package com.cndw.kungfu.controller;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.BeanUtils;

import com.cndw.commons.util.BlankUtils;
import com.cndw.kungfu.comm.PositionInspection;
import com.cndw.kungfu.config.Constants;
import com.cndw.kungfu.config.ConstantsCost;
import com.cndw.kungfu.config.ConstantsLevel;
import com.cndw.kungfu.config.ConstantsLog;
import com.cndw.kungfu.config.ConstantsModel;
import com.cndw.kungfu.config.ConstantsRadio;
import com.cndw.kungfu.config.ConstantsTask;
import com.cndw.kungfu.config.EquipType;
import com.cndw.kungfu.domain.Goods;
import com.cndw.kungfu.domain.GoodsExt;
import com.cndw.kungfu.domain.GoodsMode;
import com.cndw.kungfu.domain.Player;
import com.cndw.kungfu.domain.Scene;
import com.cndw.kungfu.exception.ErrObjectException;
import com.cndw.kungfu.exception.ErrPopException;
import com.cndw.kungfu.exception.SysErrException;
import com.cndw.kungfu.ext.LanguageLib;
import com.cndw.kungfu.ext.LogUtil;
import com.cndw.kungfu.ext.StringProcesser;
import com.cndw.kungfu.ext.TimeProcesser;
import com.cndw.kungfu.model.Context;
import com.cndw.kungfu.model.goods.PlayerBoxs;
import com.cndw.kungfu.model.goods.app.AppDo;
import com.cndw.kungfu.model.goods.domain.ModeGoodsStarSuit;
import com.cndw.kungfu.model.sys.LogServer;
import com.cndw.kungfu.vo.goodsvo.GoodsVO;
import com.cndw.rpg.annotation.Controller;
import com.cndw.rpg.framework.ResponseMessage;
import com.cndw.rpg.framework.Session;

/**
 * 背包
 * 
 * @author fantadust
 * 
 */
@Controller
public class GoodsController {

	/**
	 * 背包
	 * 
	 * @param session
	 * @return
	 */
	public ResponseMessage boxs(Session session) {
		Map<String, Object> map = new HashMap<String, Object>();
		PlayerBoxs playerBoxs = Context.getGoodsServer().getPlayerBoxs(session.getUid());
		Collection<Goods> boxGoods = playerBoxs.getBoxsGoods();

		List<GoodsVO> goodsVOs = new ArrayList<GoodsVO>();
		for (Goods e : boxGoods) {
			goodsVOs.add(e.toGoodsVO());
		}

		map.put("playerBox", goodsVOs);
		map.put("lockGoods", playerBoxs.getLockGoods());
		map.put("playerBoxsGirds", playerBoxs.getMaxGirds(PlayerBoxs.typeBox));

		return ResponseMessage.getSuccMessage(map);
	}

	/**
	 * 显示我的仓库
	 * 
	 * @param session
	 * @return
	 */
	public ResponseMessage hold(Session session) {

		Player player = Context.getPlayerServer().getByPlayerId(session.getUid());
		if (player.getLevel() < ConstantsLevel.lv16Storage) {
			return ResponseMessage.ticpErrMsg(LanguageLib.get("goods.storage.level", ConstantsLevel.lv16Storage));
		}
		Map<String, Object> map = new HashMap<String, Object>();
		PlayerBoxs playerBoxs = player.getPlayerBoxs();
		Collection<Goods> holdGoods = playerBoxs.getHoldGoods();
		List<GoodsVO> goodsVOs = new ArrayList<GoodsVO>();
		for (Goods e : holdGoods) {
			goodsVOs.add(e.toGoodsVO());
		}
		map.put("playerHold", goodsVOs);
		map.put("playerHoldGirds", playerBoxs.getMaxGirds(PlayerBoxs.typeHold));
		return ResponseMessage.getSuccMessage(map);
	}

	/**
	 * 更新属性和装备到客户端
	 * 
	 * @param session
	 * @return
	 */
	public ResponseMessage autoPlayerInfo(Session session) {
		Map<String, Object> map = new HashMap<String, Object>();
		long playerId = session.getUid();
		Player player = Context.getPlayerServer().getByPlayerId(session.getUid());

		Collection<Goods> equipGoods = player.getPlayerBoxs().getEquipList();


		List<GoodsVO> equipVOList = new ArrayList<GoodsVO>();
		for (Goods e : equipGoods) {
			equipVOList.add(e.toGoodsVO());
			if (e.isLuck()) {
				
			}
		}
//		if (havedLuck != player.getDataInfo().isHavedLuck()) {
//			player.getDataInfo().setHavedLuck(havedLuck);// 更新我是否有幸运
//		}
		String[] dressArray = new String[12];
		for (GoodsVO e : equipVOList) {
			dressArray[e.getEquipVO().position] = e.getGoodsModeVO().getIcon();
		}
		player.setDress(StringProcesser.toString(dressArray));

		Scene scene = Context.getSceneServer().getSceneById(player.getSceneId());
		if (scene != null) {
			Map<String, Object> data = new HashMap<String, Object>();
			data.put("playerId", playerId);
			data.put("dress", player.getDress());
			scene.broadcast(player, data, ConstantsRadio.equipChange);
		}

		map.put("equipList", equipVOList);
		map.put("player", player.toPlayerVO());
		List<ModeGoodsStarSuit> suit = ModeGoodsStarSuit.getStarSuite(equipGoods);
		map.put("goodsStarSuit", suit);
		Context.getGeneralServer().addTilte(player.getPlayerId(), Constants.titleUpStar, 0);

		return ResponseMessage.getSuccMessage(map);
	}

	/**
	 * 穿戴装备
	 * 
	 * @param session
	 * @param id
	 * @return
	 */
	public ResponseMessage install(Session session, int storagePlace, int target) {
		long playerId = session.getUid();
		Player player = Context.getPlayerServer().getByPlayerId(session.getUid());
		PlayerBoxs playerBoxs = player.getPlayerBoxs();

		Goods goods = playerBoxs.get(storagePlace);
		if (goods == null) {
			return null;
		}
		GoodsMode goodsMode = Context.getGoodsServer().getModeById(goods.getGoodsId());
		if (goodsMode.isEquiq() == false) {
			return null;
		} else if (goods.getStackNum() != 1) {
			LogUtil.getMain().error("goods err " + goods.info());
			return null;
		}
		if (goodsMode.getVocationId() > 0 && goodsMode.getVocationId() != player.getVocationId()) {
			return ResponseMessage.ticpErrMsg(LanguageLib.get("goods.install.viderr"));
		} else if (goodsMode.getPlayerLevel() > 0 && goodsMode.getPlayerLevel() > player.getLevel()) {
			return ResponseMessage.ticpErrMsg(LanguageLib.get("goods.install.levelerr"));
		}
		GoodsExt goodsExt = Context.getCacheCenter().getGoodsExtByLevel(goods.getGoodsId(), goods.getLevel());
		if (goodsExt == null) {
			return ResponseMessage.ticpErrMsg(LanguageLib.get("comm.err.sys"));
		}

		if (goodsMode.getPower() > player.getPower() || goodsMode.getPhysical() > player.getPhysical() || goodsMode.getAgile() > player.getAgile()
				|| goodsMode.getWit() > player.getWit()) {
			// return
			// ResponseMessage.ticpErrMsg(LanguageLib.get("goods.install.needpara"));
		}
		EquipType equipType = EquipType.convert2Type(goodsMode.getGoodTypeId());
		int position = equipType.position();
		if (target == 0) {
			target = position;
			if (position == 9) {
				if (playerBoxs.getByPostition(9) == null) {
					target = 9;
				} else if (playerBoxs.getByPostition(10) == null) {
					target = 10;
				} else if (playerBoxs.getByPostition(10).getGoodsMode().getPlayerLevel() < playerBoxs.getByPostition(9).getGoodsMode().getPlayerLevel()) {
					target = 10;
				}
			}
		} else if (target != position && !(position == 9 && target == 10)) {
			target = position;
		}

		goods.setUseNo(1);// 使装备处于使用中状态
		goods.setPosition(target);

		if (goods.getGoodsMode().getBindType() == 2 && goods.getBinding() == 0) {
			goods.setBinding(1);// 穿戴绑定
		}

		playerBoxs.execWearing(goods);
		goods.commitSync();// 同步啊

		// 更新属性
		Context.getPlayerServer().clacProperties(player);
		/**
		 * 记录一次穿戴装备
		 */
		Context.getTaskServer().notifyToSpark(playerId, ConstantsTask.spark2EquipInstall, 1);
		player.commitSync();// 提交同步 同步玩家属性
		return autoPlayerInfo(session);

	}

	/**
	 * 卸下装备
	 * 
	 * @return
	 */
	public ResponseMessage unInstall(Session session, int position, int storagePlace) {
		Player player = Context.getPlayerServer().getByPlayerId(session.getUid());
		PlayerBoxs playerBoxs = player.getPlayerBoxs();

		if (!playerBoxs.checkBlack(1)) {
			return ResponseMessage.ticpErrMsg(LanguageLib.get("comm.player.boxmin", 1));
		}

		Goods oldEquip = playerBoxs.getByPostition(position);// 暂时这么做
		if (oldEquip == null)
			return null;
		playerBoxs.execDisplay(oldEquip);

		// 更新属性
		Context.getPlayerServer().clacProperties(player);
		player.commitSync();// 提交同步
		return autoPlayerInfo(session);
	}

	/**
	 * 使用物品 一次只能使用1个
	 * 
	 * @param session
	 * @return
	 */
	public ResponseMessage use(Session session, int storagePlace) {
		long playerId = session.getUid();
		Player player = Context.getPlayerServer().getByPlayerId(playerId);
		PlayerBoxs playerBoxs = Context.getGoodsServer().getPlayerBoxs(playerId);

		Map<String, Object> dataObject = null;
		String logString = null, ticpString = null;
		synchronized (player) {
			if (!playerBoxs.containsKey(storagePlace)) {
				return ResponseMessage.ticpErrMsg(LanguageLib.get("comm.err.args"));// 物品不存在
			}
			Goods goods = playerBoxs.get(storagePlace);
			GoodsMode goodsMode = goods.getGoodsMode();
			if (goods.getStackNum() <= 0 || goodsMode.isEquiq() || goodsMode.isUseEnable() == false) {
				return ResponseMessage.ticpErrMsg(LanguageLib.get("comm.err.args"));// 不可以使用
			} else if (goodsMode.getMaxStack() < goods.getStackNum()) {
				LogUtil.getMain().error("goods err " + goods.info());
				return null;
			}
			if (goodsMode.getPlayerLevel() > player.getLevel()) {
				return ResponseMessage.ticpErrMsg(LanguageLib.get("goods.use.errlevel", goodsMode.getPlayerLevel()));
			}

			int num = 1;
			int oldNum = playerBoxs.getStackNum(goodsMode.getGoodsId());

			String appClassNeme = "com.cndw.kungfu.model.goods.app.AppDo" + goodsMode.getAppId();

			try {
				Class<?> clazz = Class.forName(appClassNeme);
				AppDo appDo = (AppDo) BeanUtils.instantiate(clazz);
				appDo.initApp(player, goodsMode, num);
				if (appDo.check()) {
					if (goods.getStackNum() <= 1) {
						playerBoxs.remove(storagePlace);
					} else {
						goods.alertStackNum(-num);
					}
					dataObject = appDo.run();
					dataObject.put("_appId", goodsMode.getAppId());
					logString = appDo.getLogString();
					ticpString = appDo.getTicpString();
				}

			} catch (ClassNotFoundException e) {
				return ResponseMessage.ticpErrMsg(LanguageLib.get("comm.err.sys"));
			} catch (SysErrException e) {
				return ResponseMessage.ticpErrMsg(LanguageLib.get("comm.err.sys"));
			} catch (ErrPopException e) {
				return ResponseMessage.ticpErrMsg(e.getMessage());
			} catch (ErrObjectException e) {
				return ResponseMessage.getFailMessage(e.getObj());
			} catch (Exception e) {
				e.printStackTrace();
			}
			LogServer.recordLog(player, ConstantsLog.goods, 70007, goodsMode.getName(), num, oldNum, logString);

		}

		return ResponseMessage.ticpMsg(ticpString, dataObject);

	}

	public ResponseMessage useAll(Session session) {
		Player player = Context.getPlayerServer().getByPlayerId(session.getUid());
		int alter = 0 ;
		
		StringBuilder sb = new StringBuilder();
		for (Goods e : player.getPlayerBoxs().getBoxsGoods()) {
			if (e.getGoodsMode() == null || e.getGoodsMode().getAppId() != 107 || e.getGoodsMode().getValueA() != 3) {
				continue;
			}
			if (e.getStackNum() > e.getGoodsMode().getMaxStack()) {
				continue;//不允许使用
			}
			int add = e.getGoodsMode().getValueB() * e.getStackNum();
			if (Integer.MAX_VALUE - alter < add) {
				continue;
			}			
			sb.append(e.getGoodsMode().getName()).append("*").append(e.getStackNum()).append(",");
			
			alter += add;			
			player.getPlayerBoxs().remove(e.getStoragePlace());
		}
		if (alter == 0) {
			return ResponseMessage.getFailMessage(false);
		}
		player.alterExpPool(alter);
		player.commitSync();
		LogServer.recordLog(player, ConstantsLog.goods, 70020, alter,sb.toString());
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("expPool", player.getExpPool());
		map.put("alter", alter);		
		return ResponseMessage.getSuccMessage(map);
	}

	/**
	 * 拆分道具
	 * 
	 * @param session
	 * @param storagePlace
	 * @param num
	 *            希望拆分出来的数量.须小于当前数量.
	 * @return 拆分出来的道具所在的id
	 */
	public ResponseMessage spilt(Session session, int storagePlace, int num) {
		PlayerBoxs playerBoxs = Context.getGoodsServer().getPlayerBoxs(session.getUid());
		Goods goods = playerBoxs.get(storagePlace);
		if (num <= 0) {
			return null;
		}
		if (goods == null || goods.getStackNum() <= num) {
			return null;
		}
		if (goods.getStackNum() > goods.getGoodsMode().getMaxStack()) {
			LogUtil.getMain().error("goods err " + goods.info());
			return null;// 非法状态下的物品
		}

		if (!playerBoxs.checkBlack(1)) {
			return ResponseMessage.ticpErrMsg(LanguageLib.get("comm.player.boxmin", 1));
		}

		goods.alertStackNum(-num);
		goods.commitSync();

		Goods goodsNew = new Goods();
		BeanUtils.copyProperties(goods, goodsNew, new String[] { "id", "storagerPlace" });
		goodsNew.setId(0);
		goodsNew.setStoragePlace(0);
		goodsNew.setStackNum(num);
		int newStoragePlace = playerBoxs.add(goodsNew);

		return ResponseMessage.getSuccMessage(newStoragePlace);
	}

	/**
	 * 丢弃某个格子的物品
	 * 
	 * @param session
	 * @param storagePlace
	 * @return
	 */
	public ResponseMessage drop(Session session, int storagePlace) {

		if (storagePlace == 0) {
			return null;
		} else {
			Player player = Context.getPlayerServer().getByPlayerId(session.getUid());
			
			if (player.getDataInfo().isGoodsLock()) {
				return ResponseMessage.ticpErrMsg(LanguageLib.get("player.pass.lockctrl"));
			}
			
			PlayerBoxs playerBoxs = player.getPlayerBoxs();
			Goods goods = playerBoxs.get(storagePlace);

			if (BlankUtils.isBlank(goods)) {
				return null;
			}
			if (goods.getStackNum() < 0) {
				return null;// 负数物品不允许丢弃.防止bug
			}
			if (goods.getStackNum() > goods.getGoodsMode().getMaxStack()) {
				LogUtil.getMain().error("goods err " + goods.info());
				return null;// 非法状态下的物品
			}
			if (goods.getGoodsMode().isTaskItem()) {//任务物品不能丢弃
				return ResponseMessage.ticpErrMsg(LanguageLib.get("goods.drop.cantdrop"));
			}
			// 添加“道具-物品丢弃”日志
			LogServer.recordLog(player, ConstantsLog.goods, 70003, goods.getGoodsMode().getName(), goods.getGoodsId(), goods.getStackNum());
			playerBoxs.remove(storagePlace);
		}

		return ResponseMessage.getSuccMessage(true);
	}

	/**
	 * 整理背包
	 * 
	 * @param session
	 * @param type
	 * @return
	 */
	public ResponseMessage classify(Session session, int type) {
		Player player = Context.getPlayerServer().getByPlayerId(session.getUid());

		if (player == null) {
			return null;
		}

		// 摆摊时不能整理背包
		if (player.stateContains(Constants.playerState64_market)) {
			return ResponseMessage.ticpErrMsg(LanguageLib.get("goods.classify.market"));
		}

		// 交易时不能整理背包
		if (player.stateContains(Constants.playerState128_trade)) {
			return ResponseMessage.ticpErrMsg(LanguageLib.get("goods.classify.trade"));
		}
		int currentTime = TimeProcesser.getUnixTime();
		int coolingTime = player.getDataInfo().getLastClassify() + 20 - currentTime;
		if (coolingTime > 2) {
			return ResponseMessage.ticpErrMsg(LanguageLib.get("goods.classify.cooling", coolingTime));
		}
		player.getDataInfo().setLastClassify(currentTime);
		player.getPlayerBoxs().classify(type);
		if (type == 0) {
			return boxs(session);
		} else {
			return hold(session);
		}

	}

	/**
	 * 移动物品
	 * 
	 * @param sourceType
	 *            源类型 0背包 1仓库
	 * @param sourcePlace
	 *            源位置
	 * @param targerType
	 *            目标类型
	 * @param targerPlace
	 *            目标位置
	 * @return int 目标位置
	 */
	public ResponseMessage moveStoragerPlace(Session session, int sourceType, int sourcePlace, int targerType, int targerPlace) {
		Player player = Context.getPlayerServer().getByPlayerId(session.getUid());
		if (sourceType == PlayerBoxs.typeHold || targerType == PlayerBoxs.typeHold) {

			if (player.getLevel() < ConstantsLevel.lv16Storage) {
				return ResponseMessage.ticpErrMsg(LanguageLib.get("goods.storage.level", ConstantsLevel.lv16Storage));
			}

			if (player.getKnight() == null || player.getKnight().isRemoteHold() == false) {
				if (PositionInspection.checkHoldPosition(player) == false) {
					return ResponseMessage.ticpErrMsg(LanguageLib.get("comm.position.err"));
				}
			}
		}

		// 摆摊时不能整理背包
		if (player.stateContains(Constants.playerState64_market)) {
			return ResponseMessage.ticpErrMsg(LanguageLib.get("goods.move.market"));
		}

		// 交易时不能整理背包
		if (player.stateContains(Constants.playerState64_market)) {
			return ResponseMessage.ticpErrMsg(LanguageLib.get("goods.move.trade"));
		}

		int finalTargerPlace = player.getPlayerBoxs().moveStoragerPlace(sourceType, sourcePlace, targerType, targerPlace);
		return ResponseMessage.getSuccMessage(finalTargerPlace);
	}
	
	/**
	 * 开启仓库格子
	 * 
	 * @param openNum
	 * 		开启数量
	 * @return ResponseMessage
	 * @author Skycat
	 */
	public ResponseMessage expandStorageCap(Session session, int openNum)
	{
		Player player = Context.getPlayerServer().getByPlayerId(session.getUid());
		
		// 最大格子数验证
		int holdGrids = player.getHoldGrids();		// 当前仓库格子数
		if ((holdGrids + openNum) > ConstantsModel.playerGirdsMaxHold)
		{
			return ResponseMessage.ticpErrMsg(LanguageLib.get("goods.expandcap.maxcap",
					ConstantsModel.playerGirdsMaxHold));
		}
		
		// 元宝验证
		int needGold = ConstantsModel.playerGridsOneOpenGold * openNum;
		if (needGold > player.getGoldAll())
		{
			return ResponseMessage.ticpErrMsg(LanguageLib.get("comm.err.gold"));
		}
		
		// 扣除元宝
		player.alterGoldAll(-needGold);
		
		// 开启格子
		holdGrids += openNum;
		player.getPlayerBoxs().activationGirds(player.getBoxsGirds(), holdGrids);	// 更新背包,仓库格子数
		player.setHoldGrids(holdGrids);			// 更新仓库格子数
		player.commitSync();
		
		// log
		LogServer.costEventLog(session.getUid(), needGold, ConstantsCost.expandStorageCap);	// 消费log
		LogServer.recordLog(player, ConstantsLog.player, 30103, openNum);			// 普通log
		
		// 返回值
		Map<String, Integer> map = new HashMap<String, Integer>(2);
		map.put("playerHoldGirds", holdGrids);		// 格子数
		map.put("gold", player.getGold());
		map.put("goldBing", player.getGoldBing());
		return ResponseMessage.getSuccMessage(map);
	}
}
